package ddu.com.config;

import com.alibaba.druid.pool.DruidDataSource;
import ddu.com.config.properties.DataProperties;
import ddu.com.myconfig.MyBeanPostProcessor;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.context.annotation.*;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import tk.mybatis.spring.mapper.MapperScannerConfigurer;

import javax.annotation.Resource;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author 张霞
 * @version 1.0
 * @项目：mammon-web-platform
 * @描述：相当于xml配置的application-context.xml，初始化spring容器--AppConfig
 * @创建时间 0:23 2018/4/15 0015
 * 作用于：配置数据源等初始化信息
 *
 */
@Slf4j
@Configuration
@PropertySource(value = "classpath:jdbc.properties")
//@Profile(value = {"dev","product"})
@ComponentScan(basePackages = {"ddu.com"}, excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, classes = Controller.class)})
//@MapperScan(basePackages = {"ddu.com.core.base","ddu.com.mapper"})//用org.mybatis.spring.annotation.MapperScan;自带的扫描
@EnableAspectJAutoProxy(proxyTargetClass = true) //使用自动代理配置，添加这个注解才能使用aop功能（开启AOP代理自动配置）
@EnableTransactionManagement  //启用注解事务管理，等同于xml配置方式的 <tx:annotation-driven />
public class RootConfig {
    private static final String[] MAPPER_LOCATIONS = {"ddu.com.core.base.BaseMapper", "ddu.com.mapper"};

    //    private static final String[] MAPPER_LOCATIONS = {"tk.mybatis.mapper.common.base", "ddu.com.mapper"};
    public RootConfig() {
        log.info("RootConfig  加载--");
    }

/*    @Autowired
    private DataProperties dataProperties;*/

    @Resource
    private Environment environment;

    @Bean
    public DataProperties dataProperties() {
        return new DataProperties();
    }

    /**
     * @auth: zhangxia
     * @desc: jdk自带 的配置数据库连接信息
     * @methodName: driverManagerDataSource
     * @params: [properties]
     * @return: javax.sql.DataSource
     * @createTime: 2018/4/18 18:26
     * @version:2.1.6
     */
    /*@Bean(name = "dataSource")
    public DataSource dataSource(){
        log.info("properties of username={}",dataProperties.getUserName());//第一种方式获取
        log.info("userName={}",environment.getProperty("druid.username"));//第二种方式获取
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName(environment.getProperty("druid.driverClassName"));
        dataSource.setUrl(environment.getProperty("druid.url"));
        dataSource.setUsername(environment.getProperty("druid.username"));
        dataSource.setPassword(environment.getProperty("druid.password"));
        return dataSource;
    }*/

    /**
     * @auth: zhangxia
     * @desc: 通过阿里数据库链接池配置数据源
     * @methodName: dataSource
     * @params: []
     * @return: com.alibaba.druid.pool.DruidDataSource
     * @createTime: 2018/4/27 17:55
     * @version:2.1.6
     */
    @Bean(name = "dataSource")
    public DruidDataSource dataSource(DataProperties dataProperties) throws SQLException {
        log.info("properties of username={}",dataProperties.getUserName());//第一种方式获取
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setDriverClassName(dataProperties.getDriverClassName());
        druidDataSource.setUrl(dataProperties.getUrl());
        druidDataSource.setUsername(dataProperties.getUserName());
        druidDataSource.setPassword(dataProperties.getPassWord());
        druidDataSource.setFilters(dataProperties.getFilters());
        druidDataSource.setMaxActive(dataProperties.getMaxActive());
        druidDataSource.setInitialSize(dataProperties.getInitialSize());
        druidDataSource.setMaxWait(dataProperties.getMaxWait());
        druidDataSource.setMinIdle(dataProperties.getMinIdle());
        druidDataSource.setTimeBetweenEvictionRunsMillis(dataProperties.getTimeBetweenEvictionRunsMillis());
        druidDataSource.setMinEvictableIdleTimeMillis(dataProperties.getMinEvictableIdleTimeMillis());
        druidDataSource.setValidationQuery(dataProperties.getValidationQuery());
        druidDataSource.setTestWhileIdle(true);
        return druidDataSource;
    }
    /**
     * @auth: zhangxia
     * @desc: 事务管理器 对mybatis操作数据库事务控制，spring使用jdbc的事务控制类
     * @methodName: transactionManager
     * @params: []
     * @return: org.springframework.jdbc.datasource.DataSourceTransactionManager
     * @createTime: 2018/4/20 10:04
     * @version:2.1.6
     */
    @Bean(name = "transactionManager")
    public DataSourceTransactionManager transactionManager(DruidDataSource druidDataSource) throws SQLException {
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(druidDataSource);
        return transactionManager;
    }

    @Bean(name = "sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactoryBean(DruidDataSource druidDataSource) throws Exception {
//        ClassPathResource classPathResource = new ClassPathResource("ddu/com/mapper/*.xml");
//        org.springframework.core.io.Resource[] mapperLocations = {classPathResource};
        SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
        factoryBean.setDataSource(druidDataSource);
//        factoryBean.setMapperLocations(mapperLocations);
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        for (String mapperLocation : MAPPER_LOCATIONS) {
            configuration.addMappers(mapperLocation);
        }
        factoryBean.setConfiguration(configuration);
        return factoryBean.getObject();
    }


    /**
     * @auth: zhangxia
     * @desc: 配置通用mapper
     * @methodName: mapperScannerConfigurer
     * @params: []
     * @return: tk.mybatis.spring.mapper.MapperScannerConfigurer
     * @createTime: 2018/4/27 17:52
     * @version:2.1.6
     */
    @Bean("mapperScanner")
    public MapperScannerConfigurer mapperScannerConfigurer(){
        MapperScannerConfigurer configurer = new MapperScannerConfigurer();
//        configurer.setBasePackage("ddu.com.mapper");//Spring会自动查找其下的类
       for (String mapperLocation : MAPPER_LOCATIONS) {
           configurer.setBasePackage(mapperLocation);
       }
        configurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
       Properties properties = new Properties();
       properties.put("style", "normal");//驼峰不转下划线
       configurer.setProperties(properties);
        return configurer;
    }




    /**
     * @auth: zhangxia
     * @desc: 装配处理器到ioc容器中
     * @methodName: initBeanPostProcessor
     * @params: []
     * @return: ddu.com.myconfig.MyBeanPostProcessor
     * @createTime: 2018/4/20 9:46
     * @version:2.1.6
     */
    @Bean(name = "myBeanPostProcessor")
    public MyBeanPostProcessor initBeanPostProcessor(){
        return new MyBeanPostProcessor();
    }


    /**
     * @auth: zhangxia
     * @desc: 加载配置文件
     * @methodName: propertySourcesPlaceholderConfigurer
     * @params: []
     * @return: org.springframework.context.support.PropertySourcesPlaceholderConfigurer
     * @createTime: 2018/4/28 11:13
     * @version:2.1.6
     */
    @Bean //要想使用@Value 用${}占位符注入属性，这个bean是必须的，这个就是占位bean,另一种方式是不用value直接用Envirment变量直接getProperty('key')
    public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
        PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
        return propertySourcesPlaceholderConfigurer;
    }


}
